package compoundDB.core;

import java.io.Serializable;
import java.util.LinkedList;
import java.util.List;

public class Atom implements Serializable {
	private AtomType m_type;
	private List<Bond> m_bonds = new LinkedList<Bond>();
	private int m_bondCount;
	
	public Atom(AtomType type) {
		m_type = type;
		m_bondCount = type.getBonds();
	}
	
	public Atom(AtomType type, int bondCount) {
		m_type = type;
		m_bondCount = bondCount;
	}
	
	public void addBond(Bond bond) {
		m_bonds.add(bond);
		
		if(m_bonds.size() > m_bondCount) {
			m_bondCount = m_bonds.size();
		}
	}
	
	public void removeBond(Bond bond) {
		if(bond.getFirstAtom() != this && bond.getSecondAtom() != this) {
			//This bond isn't even ours - should probably throw an exception
			return;
		}
		
		//Decrement the number of bonds...
		m_bondCount--;
		
		if(m_bonds.contains(bond)) {
			m_bonds.remove(bond);
		}
		
		//If it wasn't in the list, we'll assume that it's one of our implicit bonds being removed.
		//This probably needs some rethinking.
	}
	
	public List<Bond> getBonds() {
		List<Bond> allBonds = new LinkedList<Bond>();
		allBonds.addAll(m_bonds);
		while(allBonds.size() < m_bondCount) {
			Atom implicitH = new Atom(AtomType.H);
			Bond implicitBond = new Bond(Bond.BondType.SINGLE, this, implicitH);
			allBonds.add(implicitBond);
		}
		
		return allBonds;
	}
	
	public AtomType getType() {
		return m_type;
	}
	
	public enum AtomType {
		H	{ int getBonds() {return 1; } },
		He	{ int getBonds() {return 0; } },
		Li	{ int getBonds() {return 1; } },
		Be	{ int getBonds() {return 2; } },
		B	{ int getBonds() {return 3; } },
		C	{ int getBonds() {return 4; } },
		N	{ int getBonds() {return 3; } },
		O	{ int getBonds() {return 2; } },
		F	{ int getBonds() {return 1; } },
		Ne	{ int getBonds() {return 0; } },
		Na	{ int getBonds() {return 1; } },
		Mg	{ int getBonds() {return 2; } },
		Al	{ int getBonds() {return 3; } },
		Si	{ int getBonds() {return 4; } },
		P	{ int getBonds() {return 3; } },
		S	{ int getBonds() {return 2; } },
		Cl	{ int getBonds() {return 1; } },
		Ar	{ int getBonds() {return 0; } },
		K	{ int getBonds() {return 1; } },
		Ca	{ int getBonds() {return 2; } };
		/*etc...*/
		
		abstract int getBonds();
	}
}
